package com.vhall.component.service.chat.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.vhall.component.dao.lottery.LotteryJoinsMapper;
import com.vhall.component.entity.account.enums.RoleNameEnum;
import com.vhall.component.entity.chat.vo.*;
import com.vhall.component.entity.lottery.entity.LotteryJoinsEntity;
import com.vhall.component.entity.paas.PaasMessageListRspDTO;
import com.vhall.component.entity.room.dto.RoomJoinsEntityDTO;
import com.vhall.component.entity.room.dto.RoomsEntityDTO;
import com.vhall.component.framework.common.constant.CommonConstant;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.framework.common.utils.CollectionUtils;
import com.vhall.component.plugin.common.constant.HttpConstant;
import com.vhall.component.plugin.common.constant.PaasCommonConstant;
import com.vhall.component.plugin.common.constant.RedisKey;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.common.support.Token;
import com.vhall.component.plugin.common.support.TokenThreadLocal;
import com.vhall.component.plugin.common.utils.*;
import com.vhall.component.plugin.core.service.OssService;
import com.vhall.component.plugin.core.service.PaasService;
import com.vhall.component.plugin.core.service.event.PaasMessageReqDTO;
import com.vhall.component.service.chat.ChatService;
import com.vhall.component.service.room.RoomInnerService;
import com.vhall.component.service.room.RoomJoinService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.net.URLDecoder;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author guoxin.wang
 * @date 2021/5/28 10:15
 */
@Slf4j
@Service
public class ChatServiceImpl implements ChatService {

    @Autowired
    private RoomInnerService roomInnerService;

    @Autowired
    private PaasService paasService;

    @Autowired
    private OssService ossService;
    @Autowired
    private LotteryJoinsMapper lotteryJoinsMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @Override
    public Map<String, Object> lists(ChatListReqVo reqVo) {
        //room_id验证
        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(reqVo.getRoomId());
        if (roomInfo == null) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }

        HashMap<String, Object> params = new HashMap<>(8);
        params.put(PaasCommonConstant.CHANNEL_ID_KEY, roomInfo.getChannelId());
        params.put(PaasCommonConstant.MSG_TYPE_KEY, reqVo.getType());
        Integer pageSize = reqVo.getPageSize() == null ? 20 : reqVo.getPageSize();
        params.put(PaasCommonConstant.PAGE_SIZE_KEY, pageSize);
        params.put(PaasCommonConstant.ORDER_BY, reqVo.getOrderBy());
        params.put("filter_status", 0);
        //PaaS接收的start_time实际是String类型
        LocalDateTime localTime = reqVo.getStartDate() == null ? roomInfo.getCreatedAt() : reqVo.getStartDate();
        DateTimeFormatter df = DateTimeFormatter.ofPattern(CommonConstant.DATETIME_FORMAT);
        String startTime = df.format(localTime);
        params.put(PaasCommonConstant.START_TIME_KEY, startTime);

        Integer currPage = reqVo.getCurrPage() == null || reqVo.getCurrPage() == 0 ? 1 : reqVo.getCurrPage();
        params.put(PaasCommonConstant.CURR_PAGE_KEY, currPage);
        //发送消息到PaaS
        JSONObject data = paasService.getMessageLists(params);
        //处理响应消息
        List<JSONObject> rspLists = (List) data.getJSONArray("list");

        //三方用户Id集合
        List<String> thirdPartyUserIdList = new ArrayList<>();

        //roomJoins中数据
        HashMap<Integer, RoomJoinsEntityDTO> userListArr = new HashMap<>(16);
        ArrayList<Object> arrayList = new ArrayList<>();
        if (rspLists != null) {
            //将响应数据中所有三方用户ID取出来
            rspLists.forEach(list -> thirdPartyUserIdList.add(list.getString(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY)));

            String accountIds = JSON.toJSONString(thirdPartyUserIdList);

            List<RoomJoinsEntityDTO> lists = roomInnerService.getRoomInfoByAccountIds(roomInfo.getRoomId(), accountIds);

            lists.forEach(list -> userListArr.put(list.getAccountId(), list));

            Collections.reverse(rspLists);
            rspLists.forEach(list -> {
                Map<String, Object> map = new HashMap<>(4);
                ChatListRspVo chArr = new ChatListRspVo();
                map.put("type", list.getString("type"));
                map.put("text_content", list.getString(HttpConstant.DATA));
                RoomJoinsEntityDTO roomJoins = userListArr.get(list.getInteger(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY));
                String nickname = StringUtils.isBlank(roomJoins.getNickname()) ? "" : roomJoins.getNickname();
                String avatar = StringUtils.isBlank(roomJoins.getAvatar()) ? "" : roomJoins.getAvatar();
                String roleName = StringUtils.isBlank(roomJoins.getRoleName()) ? "" : roomJoins.getRoleName();
                if (StringUtils.isNotBlank(list.getString(PaasCommonConstant.IMAGE_URLS_KEY))) {
                    map.put("image_urls", list.getJSONArray(PaasCommonConstant.IMAGE_URLS_KEY));
                }

                chArr.setData(map)
                        .setDateTime(list.getDate("date_time").toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime())
                        .setSenderId(list.getString(PaasCommonConstant.IMAGE_URLS_KEY))
                        .setNickname(nickname)
                        .setAvatar(avatar)
                        .setRoleName(roleName)
                        .setMsgId(list.getString(PaasCommonConstant.MSG_ID_KEY))
                        .setContext(list.getJSONObject("context").getInnerMap())
                        .setChannelId(roomInfo.getChannelId());
                arrayList.add(chArr);
            });
        }
        Map<String, Object> result = new HashMap<>(4);
        result.put("page", data.get("page_num"));
        result.put("last_page", data.get("page_all"));
        result.put("list", arrayList);
        return result;
    }

    /**
     * 历史聊天消息（优化版）
     *
     * @param reqVo 请求参数
     * @return 响应数据
     * @author yuanzh
     * @date 2021/9/24
     */
    @Override
    public Map<String, Object> listMessage(ChatListReqVo reqVo) {
        // room_id验证
        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(reqVo.getRoomId());
        if (roomInfo == null) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }

        Map<String, Object> paasParam = new HashMap<>(8);
        String channelId = roomInfo.getChannelId();
        paasParam.put(PaasCommonConstant.CHANNEL_ID_KEY, channelId);
        paasParam.put(PaasCommonConstant.MSG_TYPE_KEY, reqVo.getType());
        int pageSize = reqVo.getPageSize() == null ? 20 : reqVo.getPageSize();
        int currentPage = reqVo.getCurrPage() == null || reqVo.getCurrPage() == 0 ? 1 : reqVo.getCurrPage();
        paasParam.put(PaasCommonConstant.CURR_PAGE_KEY, currentPage);
        paasParam.put(PaasCommonConstant.PAGE_SIZE_KEY, pageSize);
        paasParam.put(PaasCommonConstant.ORDER_BY, reqVo.getOrderBy());
        paasParam.put("filter_status", 0);
        LocalDateTime localTime = reqVo.getStartDate() == null ? roomInfo.getCreatedAt() : reqVo.getStartDate();
        paasParam.put(PaasCommonConstant.START_TIME_KEY, DateUtil.format(localTime, CommonConstant.DATETIME_FORMAT));

        LocalDateTime endTime = reqVo.getEndDate() == null ? null : reqVo.getEndDate();
        if (endTime != null) {
            paasParam.put(PaasCommonConstant.END_TIME_KEY, DateUtil.format(endTime, CommonConstant.DATETIME_FORMAT));
        }
        // 缓存key，ch:{channelId}:msg:{param_base64}
        String msgCacheKey = String
                .format("ch:%s:msg:%s", channelId, Base64Coding.encode(JsonUtil.toJsonString(new TreeMap<>(paasParam))));
        BoundValueOperations<String, String> cacheOps = redisTemplate.boundValueOps(msgCacheKey);
        PaasMessageListRspDTO paasMessageList = JsonUtil.objectFromJSONString(cacheOps.get(), PaasMessageListRspDTO.class);
        // 若缓存中无消息，则请求paas获取历史聊天记录
        if (Objects.isNull(paasMessageList)) {

            String key = MessageFormat.format("{0}:{1}", RedisKey.NO_CHAT, msgCacheKey);

            if (redisTemplate.opsForValue().get(key) != null) {
                Map<String, Object> before = new HashMap<>(4);
                List<ChatListRspVo2> record = new ArrayList<>();
                before.put("page", currentPage);
                before.put("last_page", 0);
                before.put("list", JsonUtil.arrayFromJSONString(JsonUtil.toJsonString(record), JSONObject.class));
                before.put("no_chat", 0);
                return before;
            }


            String lockValue = "1";
            if (!RedisLocker.tryLock(msgCacheKey, lockValue, 10 * 1000L)) {
                try {
                    Thread.sleep(50L);
                } catch (InterruptedException e) {
                    log.error("Interrupted!", e);
                    Thread.currentThread().interrupt();
                }
                return listMessage(reqVo);
            }
            try {
                paasMessageList = paasService.getMessageList2(paasParam);
                // 读取到消息列表之后缓存处理
                if (Objects.nonNull(paasMessageList) && paasMessageList.getTotal() > 0) {
                    // 缓存失效时间，随机5到10秒
                    int expireSeconds = RandomUtil.getRandomNum(1, 3);
                    cacheOps.set(JsonUtil.toJsonString(paasMessageList), expireSeconds, TimeUnit.SECONDS);
                } else {
                    //缓存 空
                    int expireSeconds = RandomUtil.getRandomNum(1, 3);
                    redisTemplate.opsForValue().set(key, RedisKey.NO_CHAT, expireSeconds, TimeUnit.SECONDS);
                }


            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                RedisLocker.unlock(msgCacheKey, lockValue);
            }
        }

        int totalPage = 0;
        List<ChatListRspVo2> recordList = new ArrayList<>();
        if (Objects.nonNull(paasMessageList) && CollectionUtils.isNotEmpty(paasMessageList.getList())) {
            List<PaasMessageListRspDTO.PaasChatRecord> chatRecordList = paasMessageList.getList();
            Collections.reverse(chatRecordList);

            // 根据用户ids获取聊天者参与信息
            String accountIds = JSON.toJSONString(paasMessageList.getAllUserId());
            List<RoomJoinsEntityDTO> roomJoinsDTOList = roomInnerService.getRoomInfoByAccountIds(roomInfo.getRoomId(), accountIds);
            Map<String, RoomJoinsEntityDTO> roomJoinsMap = new HashMap<>(16);
            // 以用户id为key，参与信息为value，转换参会列表
            roomJoinsDTOList.forEach(item -> roomJoinsMap.put(String.valueOf(item.getAccountId()), item));

            // 转换聊天记录
            for (PaasMessageListRspDTO.PaasChatRecord chatRecord : chatRecordList) {
                RoomJoinsEntityDTO roomJoins = roomJoinsMap.get(chatRecord.getThirdPartyUserId());
                try {
                    ChatListRspVo2 chatListRspVo = new ChatListRspVo2.Builder(chatRecord).initUserInfo(roomJoins).build();
                    chatListRspVo.setChannelId(channelId);
                    recordList.add(chatListRspVo);
                } catch (Exception e) {
                    log.error("chat history list parse error {},{}", e.getMessage(), e.getCause());
                }
            }
            totalPage = paasMessageList.getTotalPage();
        }
        // 组装返回数据
        Map<String, Object> result = new HashMap<>(4);

        result.put("page", currentPage);
        result.put("last_page", totalPage);
        result.put("list", JsonUtil.arrayFromJSONString(JsonUtil.toJsonString(recordList), JSONObject.class));
        return result;
    }

    @Override
    public Map<String, AuditListRspVo> auditLists(ChatAuditListReqVo reqVo) {
        Map<String, AuditListRspVo> resultMap = new LinkedHashMap<>();

        Map<String, Object> param = new HashMap<>(4);
        param.put("room_id", reqVo.getRoomId());
        param.put(PaasCommonConstant.CHANNEL_ID_KEY, reqVo.getChannelId());
        param.put(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY, reqVo.getThirdPartyUserId());
        param.put(PaasCommonConstant.CLIENT_KEY, reqVo.getClient());
        JSONObject auditLists = paasService.auditLists(param);
        if (auditLists == null) {
            return resultMap;
        }
        Map<String, Object> innerMap = auditLists.getInnerMap();

        ArrayList<Integer> senderIdList = new ArrayList<>();
        Set<String> keys = innerMap.keySet();
        //获取senderid
        keys.forEach(key -> {
            AuditListRspVo auditListRspVo = new AuditListRspVo();
            String s = JSON.toJSONString(innerMap.get(key));
            AuditListsToPaasDto dto = JSON.parseObject(JSON.parse(s).toString(), AuditListsToPaasDto.class);
            BeanUtils.copyProperties(dto, auditListRspVo);
            senderIdList.add(auditListRspVo.getSenderId());
            resultMap.put(key, auditListRspVo);
        });

        List<Map.Entry<String, AuditListRspVo>> mapList = new ArrayList<Map.Entry<String, AuditListRspVo>>(resultMap.entrySet());

        Collections.sort(mapList, new Comparator<Map.Entry<String, AuditListRspVo>>() {
            @Override
            public int compare(Map.Entry<String, AuditListRspVo> o1,
                               Map.Entry<String, AuditListRspVo> o2) {
                /**
                 * 按年龄升序(if条件和返回值相同) 年龄相同 按成绩降序(if条件和返回值相反)
                 */
                if (o1.getValue().getTime().isAfter(o2.getValue().getTime())) {
                    return 1;
                } else {
                    return -1;
                }

            }

        });

        resultMap.clear();

        for (Map.Entry<String, AuditListRspVo> stringAuditListRspVoEntry : mapList) {
            resultMap.put(stringAuditListRspVoEntry.getKey(), stringAuditListRspVoEntry.getValue());
        }


        //添加消息发送人禁言和踢出状态
        String senderIds = JSON.toJSONString(senderIdList);
        Map<Integer, RoomJoinsEntityDTO> map = roomInnerService.getRoomInfoBySenderIds(reqVo.getRoomId(), senderIds);
        resultMap.keySet().forEach(key -> {

            AuditListRspVo item = resultMap.get(key);
            Integer isKicked = null;
            Integer isBanned = null;
            if (map.size() != 0) {
                if (item.getSenderId() != null) {
                    isBanned = map.get(item.getSenderId()).getIsBanned();
                    isKicked = map.get(item.getSenderId()).getIsKicked();
                }
            }
            isBanned = isBanned != null ? isBanned : 0;
            isKicked = isKicked != null ? isKicked : 0;
            item.setIsBanned(isBanned);
            item.setIsKicked(isKicked);
        });
        return resultMap;
    }

    @Override
    public JSONObject messageLists(MessageListsReqVo reqVo) {
        Map<String, Object> map = new HashMap<>(8);
        map.put(PaasCommonConstant.CHANNEL_ID_KEY, reqVo.getChannelId());
        map.put(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY, reqVo.getThirdPartyUserId());
        map.put(PaasCommonConstant.CLIENT_KEY, reqVo.getClient());
        map.put(PaasCommonConstant.START_TIME_KEY, reqVo.getStartTime());
        String msgType = StringUtils.isNotBlank(reqVo.getMsgType()) ? reqVo.getMsgType() : "all";
        map.put(PaasCommonConstant.MSG_TYPE_KEY, msgType);
        Integer currPage = reqVo.getCurrPage() != null ? reqVo.getCurrPage() : 1;
        map.put(PaasCommonConstant.CURR_PAGE_KEY, currPage);
        Integer pageSize = reqVo.getPageSize() != null ? reqVo.getPageSize() : 200;
        map.put(PaasCommonConstant.PAGE_SIZE_KEY, pageSize);
        JSONObject messageLists = paasService.getMessageLists(map);
        if (messageLists != null) {
            JSONArray list = messageLists.getJSONArray("list");
            if (null != list && list.size() > 0) {
                for (int i = 0; i < list.size(); i++) {
                    JSONObject jsonObject = list.getJSONObject(i);
                    String thirdPartyUserId = jsonObject.getString(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY);
                    if (StringUtils.isNotBlank(thirdPartyUserId)) {
                        jsonObject.put(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY, Integer.parseInt(thirdPartyUserId));
                    }
                }
            }
        }
        return messageLists;
    }

    @Override
    public JSONObject setChannelSwitch(ChannelSwitchSetReqVo reqVo) {

        Map<String, Object> map = new HashMap<>(4);
        map.put("switch", reqVo.getChannelSwitch());
        map.put(PaasCommonConstant.CHANNEL_ID_KEY, reqVo.getChannelId());
        map.put(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY, reqVo.getThirdPartyUserId());
        map.put(PaasCommonConstant.CLIENT_KEY, reqVo.getClient());
        return paasService.setChannelSwitch(map);
    }

    @Override
    public JSONObject getChannelSwitch(ChannelSwitchReqVo reqVo) {
        Map<String, Object> map = new HashMap<>(4);
        map.put(PaasCommonConstant.CHANNEL_ID_KEY, reqVo.getChannelId());
        map.put(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY, reqVo.getThirdPartyUserId());
        map.put(PaasCommonConstant.CLIENT_KEY, reqVo.getClient());
        return paasService.getChannelSwitch(map);
    }

    @Override
    public JSONObject setChannelSwitchOptions(ChannelSwitchOptionReqVo reqVo) {
        Map<String, Object> map = new HashMap<>(8);
//        app_id: fGWLbDnj
//        client: pc_browser
//        vss_token: access:fGWLbDnj:7263fa4c753af99d
//        channel_id: ch_6Euv24U3
//        third_party_user_id: 15197
//        switch: 2
//        switch_options: 2
//        from: js
//        token: 7b5f9a882f427471
        map.put("switch", reqVo.getChannelSwitch());
        map.put(PaasCommonConstant.CHANNEL_ID_KEY, reqVo.getChannelId());
        map.put(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY, reqVo.getThirdPartyUserId());
        map.put(PaasCommonConstant.CLIENT_KEY, reqVo.getClient());
        map.put("switch_options", reqVo.getSwitchOptions());
        return paasService.setChannelSwitchOptions(map);
    }

    @Override
    public Boolean applyMessageSend(ApplyMessageSendReqVO reqVO) {

        String msgIds = reqVO.getMsgId();

        String[] ids = msgIds.split(",");

        if (ids.length >= 20) {

            List<String> resultList = new ArrayList<>(ids.length);
            Collections.addAll(resultList, ids);

            int pageCount = ids.length % 20 == 0 ? ids.length / 20 : ids.length / 20 + 1;

            List<List<String>> afterList = ListUtils.spiltList(resultList, pageCount);
            if (CollectionUtils.isNotEmpty(afterList)) {
                for (List<String> stringList : afterList) {
                    if (CollectionUtils.isNotEmpty(stringList)) {
                        log.info("拆分数据开始");
                        String allids = ListUtils.listToString(stringList, ",");
                        log.info("拆分消息ids " + allids);
                        Map<String, Object> map = new HashMap<>(8);
                        map.put(PaasCommonConstant.STATUS, reqVO.getStatus());
                        map.put(PaasCommonConstant.CHANNEL_ID_KEY, reqVO.getChannelId());
                        map.put(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY, reqVO.getThirdPartyUserId());
                        map.put(PaasCommonConstant.CLIENT_KEY, reqVO.getClient());
                        map.put(PaasCommonConstant.VSS_TOKEN, reqVO.getVssToken());
                        map.put(PaasCommonConstant.MSG_ID_KEY, allids);
                        map.put("from", reqVO.getFrom());
                        paasService.applyMessageSend(map);
                        log.info("拆分数据结束");
                    }
                }
            }
        } else {
            Map<String, Object> map = new HashMap<>(8);
            map.put(PaasCommonConstant.STATUS, reqVO.getStatus());
            map.put(PaasCommonConstant.CHANNEL_ID_KEY, reqVO.getChannelId());
            map.put(PaasCommonConstant.THIRD_PARTY_USER_ID_KEY, reqVO.getThirdPartyUserId());
            map.put(PaasCommonConstant.CLIENT_KEY, reqVO.getClient());
            map.put(PaasCommonConstant.VSS_TOKEN, reqVO.getVssToken());
            map.put(PaasCommonConstant.MSG_ID_KEY, msgIds);
            map.put("from", reqVO.getFrom());
            paasService.applyMessageSend(map);
        }
        return true;
    }

    @Override
    public Map<String, Object> upload(ChatUploadReqVo reqVo) {
        Map<String, Object> map = new HashMap<>(4);
        try {
            String name = IdUtil.fastSimpleUUID();
            String ext = FileNameUtil.extName(reqVo.getFile().getOriginalFilename());
            name = name + "." + ext;
            MultipartFile image = reqVo.getFile();
            String type = image.getContentType();
            String result = ossService.upload(image.getInputStream(), name, type);
            log.info("文件上传结果,{}", JSON.toJSONString(result));
            map.put("url", result);
        } catch (Exception ex) {
            log.error("图片上传失败:", ex);
        }
        return map;
    }

    @Override
    public Map<String, Object> imageUpload(String imgBase64) {
        Map<String, Object> map = new HashMap<>(4);
        try {

            if (StringUtils.isAllEmpty(imgBase64)) {
                return map;
            }
            imgBase64 = imgBase64.replaceAll("\\+", "%2B");
            String image = URLDecoder.decode(imgBase64, CommonConstant.UTF8);

            byte[] bytes = Base64Utils.decodeFromString(image);
            String type = "image/jpeg";
            String name = IdUtil.fastSimpleUUID() + ".jpg";
            ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
            String result = ossService.upload(stream, name, type);
            log.info("文件上传结果,{}", JSON.toJSONString(result));
            map.put("url", result);
        } catch (Exception ex) {
            log.error("图片上传失败:", ex);
        }
        return map;
    }

    @Override
    public Boolean sendMessage(SendMessageReqVO reqVO) {
        // 此处roomId 实际上 前端传过来的是il_id
        String roomId = reqVO.getRoomId();
        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(roomId);
        if (Objects.isNull(roomInfo)) {
            roomInfo = Optional.ofNullable(roomInnerService.getRoomInfoByIlId(roomId)).orElseThrow(() -> new BusinessException(BizErrorCode.EMPTY_ROOM));
            roomId = roomInfo.getRoomId();
        }
        Token token = TokenThreadLocal.getToken();
        JSONObject contextJson = new JSONObject();
        contextJson.put("nickname", token.getNickname());
        contextJson.put("avatar", "");
        Integer roleName = token.getRoleName();
        contextJson.put("role_name", roleName);
        JSONObject replyMsg = reqVO.getReplyMsg();
        if (Objects.nonNull(replyMsg)) {
            contextJson.put("replyMsg", replyMsg);
        } else {
            contextJson.put("replyMsg", new JSONObject());
        }
        JSONArray atList = reqVO.getAtList();
        if (Objects.nonNull(atList)) {
            contextJson.put("atList", atList);
        } else {
            contextJson.put("atList", new JSONArray());
        }

        if (Objects.equals(roleName, RoleNameEnum.AUDIENCE.getValue())) {
            contextJson.put("roleNameText", "{}");
        } else {
            JSONObject roleNameTextJson = new JSONObject();
            roleNameTextJson.put("text", RoleNameEnum.getNameByValue(roleName));
            roleNameTextJson.put("type", "");
            String roleNameText = roleNameTextJson.toJSONString();
            contextJson.put("roleNameText", roleNameText);
        }

        String context = contextJson.toJSONString();
        PaasMessageReqDTO paasMessageReq = new PaasMessageReqDTO();
        paasMessageReq.setType("service_im");
        String client = reqVO.getClient();
        paasMessageReq.setClient(StrUtil.isNotBlank(client) ? client : "pc_browser");
        paasMessageReq.setChannelId(roomInfo.getChannelId());
        paasMessageReq.setThirdUserId(token.getAccountId() + "");
        paasMessageReq.setRoomId(roomInfo.getRoomId());
        paasMessageReq.setIsCache(1);

        RoomJoinsEntityDTO joins = roomInnerService.getRoomJoins(token.getAccountId(), roomInfo.getRoomId());
        if (joins == null || joins.getRoleName().equals("2") || joins.getRoleName().equals("4")) {
            paasMessageReq.setBody(reqVO.getBody().toJSONString());
        } else {
            JSONObject body = reqVO.getBody();
            body.put("access_audit", 0);
            paasMessageReq.setBody(body.toJSONString());
        }
        paasMessageReq.setContext(context);
        paasService.sendMessage(paasMessageReq);
        JSONObject body = reqVO.getBody();
        String content = body.getString("text_content");
        log.info("聊天内容：{}", body);
        if (StrUtil.isNotEmpty(content)) {
            lotteryCheck(roomInfo.getIlId(), roomInfo.getRoomId(), token.getAccountId(), content);
        }
        return true;
    }

    private void lotteryCheck(Integer ilId, String roomId, Integer accountId, String reqComment) {
        String key = RedisKey.KEY_LOTTERY_TYPE_COMMENT + roomId;
        if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
            String s = String.valueOf(redisTemplate.opsForValue().get(key));
            JSONObject jsonObject = JSONObject.parseObject(s);
            Integer lotteryId = jsonObject.getInteger("lotteryId");
            String comment = jsonObject.getString("comment");
            if (!comment.equals(reqComment)) {
                return;
            }
            String commentKey = RedisKey.KEY_LOTTERY_COMMENT_JOIN + lotteryId;
            redisTemplate.opsForSet().add(commentKey, String.valueOf(accountId));
            redisTemplate.expire(commentKey, 10, TimeUnit.MINUTES);
            log.info("抽奖评论成功,roomId:{},lotteryId:{},accountId:{}", roomId, lotteryId, accountId);
        }
    }


}

